#include <bits/stdc++.h>

using namespace std;

/*
	4096 3 2 3 4
	-1 2 3 4 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 0
	16777216 6 1 5 6 9 10 13
	1 -1 -1 -1 5 6 -1 -1 9 10 -1 -1 13 -1 -1 0
	16777216 6 7 8 11 12 14 15
	-1 -1 -1 -1 -1 -1 7 8 -1 -1 11 12 -1 14 15 0
*/

struct State{
	int state[4][4];
	unsigned figure; //作为标识用来判重,同时用于输出的哈希
	unsigned zeromask;
	short depth;
	pair<int,int> zero;
};

int numbersize;
int numbers[6];

int outputsize;

short output[16777216];



void count_figure(State& x)
{
	unsigned figure = 0;

	for(int i = 0; i < 16; i ++) {
		int row = i / 4;
		int col = i % 4;
		for(int j = 0; j < numbersize; j ++) {
			if(x.state[row][col] == numbers[j]) {
				figure |= (i << (j << 2));
				break;
			}
			if(x.state[row][col] == 0) {
				x.zeromask = i;
				break;
			}
		}
	}
	x.figure = figure;
}

void find_zero(State& x)
{
	for(int i = 0; i < 4; i ++)
		for(int j = 0; j < 4; j ++)
			if(x.state[i][j] == 0) {
				x.zero.first = i;
				x.zero.second = j;
				x.zeromask = i * 4 + j;
				return;
			}
}

bool check(int x)
{
	for(int i = 0; i < numbersize; i ++) {
		if(x == numbers[i]) return true;
	}
	return false;
}

unsigned locatex(int x, int p4, int p3, int p2)
{
	return ((x << 12) + (p4 << 8) + (p3 << 4) + (p2));
}

unsigned locate1(int p4, int p3, int p2)
{
	return ((p4 << 8) + (p3 << 4) + (p2));
}

void bfs(State start)
{
	queue<State> QS;
	set<unsigned> vis;

	unsigned hash_start = start.figure | (start.zeromask << (numbersize << 2));

	vis.insert(hash_start);

	output[start.figure] = 0;

	QS.push(start);

	int dir[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};


	while(!QS.empty()) {

		State t = QS.front();

		//debug
		// unsigned hasht = t.figure | (t.zeromask << (numbersize << 2));
		// if(hasht == locatex(0, 1, 6, 5)) cout << t.depth << endl;

		if(output[t.figure] == -1) output[t.figure] = t.depth;
		else output[t.figure] = min(t.depth, output[t.figure]);

		QS.pop();
		int i = t.zero.first, j = t.zero.second;
		// cout << endl << i << ' ' << j << endl;
		for(int k = 0; k < 4; k ++) {
			int ni = i + dir[k][0], nj = j + dir[k][1];

			if(ni < 4 && ni >= 0 && nj < 4 && nj >= 0) {
				State ns;
				for(int ii = 0; ii < 4; ii ++) {
					for(int jj = 0; jj < 4; jj ++) {
						ns.state[ii][jj] = t.state[ii][jj];
					}
				}

				int legal_depth = 0;
				if(check(ns.state[ni][nj])) legal_depth ++;
				ns.depth = t.depth + legal_depth;

				int temp = ns.state[ni][nj];
				ns.state[ni][nj] = ns.state[i][j];
				ns.state[i][j] = temp;

				count_figure(ns);
				find_zero(ns);

				// if(hasht == locatex(2, 1, 6, 5)) {

				// }

				unsigned hash = ns.figure | (ns.zeromask << (numbersize << 2));

				if(vis.find(hash) == vis.end()) {
					QS.push(ns);
					vis.insert(hash);
					
				} else if(ns.depth < output[ns.figure])
					QS.push(ns);
			}
		}
	}
}

int main()
{
	int state[16];

	for(int t = 0; t < 3; t ++) {
		memset(output, -1, sizeof output);

		cin >> outputsize;
		cin >> numbersize;

		for(int i = 0; i < numbersize; i ++) 
			cin >> numbers[i];

		for(int i = 0; i < 16; i ++)
			cin >> state[i];

		int k = 0;

		State start;
		for(int i = 0; i < 4; i ++) {
			for(int j = 0; j < 4; j ++) {
				start.state[i][j] = state[k ++];
			}
		}

		count_figure(start);
		find_zero(start);
		
		start.depth = 0;
		bfs(start);

		ofstream fout;
		char st = '0' + t;
		string name = "db";
		name = name + st;
		name = name + ".db";
		fout.open(name, ios::out);

		if(!fout) {
			cout << "error!"<< endl;
		}

		for(int i = 0; i < outputsize; i ++) {
			fout << output[i] << ' ';
		}

		//debug
		// cout << output[locate1(0, 6, 5)] << endl;

		fout.close();
	}

	return 0;
}
